/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.akro.smsc;

import ie.omk.smpp.Connection;
import ie.omk.smpp.event.ConnectionObserver;
import ie.omk.smpp.event.ReceiverExitEvent;
import ie.omk.smpp.event.SMPPEvent;
import ie.omk.smpp.message.SMPPPacket;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Jose Carlos Palma
 */
public class SMSCReceiver extends Thread implements ConnectionObserver{
    
    private String ip;
    private int port;
    private Connection conn;
    
    private final Logger log = Logger.getLogger(SMSCReceiver.class.getName());
    
    
    public static final int RECEIVER = Connection.RECEIVER;
    public static final int TRANSMITTER = Connection.TRANSMITTER;
    public static final int TRANSCEIVER = Connection.TRANSCEIVER;
    
    
    public SMSCReceiver(String ip, int port){
        this.ip = ip;
        this.port = port;
    }

    @Override
    public void run() {
        
        try {
            conn = new Connection(ip, port, true);
        } catch (UnknownHostException ex) {
            log.log(Level.SEVERE, null, ex);
        }
        
        conn.addObserver(this);
        conn.autoAckLink(true);
        conn.autoAckMessages(true);
        
        log.info("Binding to the SMSC...");
        
        synchronized(this){
            try {
                conn.bind(RECEIVER, "VMSC3", "VMSC31", null);
                wait();
            } catch (IOException ex) {
                log.log(Level.SEVERE, null, ex);
            } catch (InterruptedException ex) {
                log.log(Level.SEVERE, null, ex);
            }
            
            try {
                conn.closeLink();
            } catch (IOException ex) {
                log.log(Level.SEVERE, null, ex);
            }
            
            
        }
        
        
    }

    @Override
    public void packetReceived(Connection source, SMPPPacket packet) {
        
        switch (packet.getCommandId()) {
            case SMPPPacket.BIND_RECEIVER_RESP:
                if(packet.getCommandStatus() != 0){
                    log.log(Level.SEVERE, "Error bindind to SMSC: {0} ", packet.getCommandStatus());
                }else {
                
                    log.log(Level.INFO, "Bind Receiver Resp");
                    synchronized (this){
                        System.out.println("OK");
                    }
                }
                break;
                
            case SMPPPacket.DELIVER_SM:
                log.log(Level.INFO, "Deliver SMS");
                break;
            
            case SMPPPacket.UNBIND:
                log.log(Level.INFO, "Unbind");
                break;
            
            case SMPPPacket.UNBIND_RESP:
                log.log(Level.INFO, "Unbind Resp");
                break;
            
            default:
                String id = Integer.toHexString(packet.getCommandId());
                log.log(Level.INFO, "Unexpected packet received! id = 0x{0}",id);
        }
        
    }

    @Override
    public void update(Connection source, SMPPEvent ev) {
        
        switch (ev.getType()) {
            case SMPPEvent.RECEIVER_EXIT:
                receiverExit(source, (ReceiverExitEvent)ev);
                break;
            default:
                
                log.log(Level.INFO, "[ERR]");
        }
        
    }
    
    private void receiverExit(Connection source, ReceiverExitEvent ev){
        if( ev.getReason() != ReceiverExitEvent.EXCEPTION ){
            //if( ev.getReason() == ReceiverExitEvent.BIND_TIMEOUT )
            log.log(Level.SEVERE, "Receiver has exited: {0}", ev.getReason());
            
        }else{
            log.log(Level.SEVERE, "Receiver died due to exception:",ev.getException());
        }
        
        synchronized (this){
            notify();
        }
    }
    
    
    
    
    
}
